package com.sl.core.engine.rowset;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Maps;
import com.sl.core.engine.trans.ProcessInstance;
import com.sl.core.engine.trans.ProcessTrans;
import lombok.SneakyThrows;
import org.apache.commons.compress.utils.Lists;

import javax.sql.DataSource;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class ProcessFileRowSet extends ProcessAbstractDbRowSet {


    public ProcessFileRowSet(ProcessTrans processTrans) {
        super(processTrans);
        //创建文件
        //创建文件
//        initFiles();
    }

    @Override
    public List<Map<String, Object>> searchStepList(String date, String processId, String processVersion, String tid, String dbFile) {
        File rootFile = ProcessFileRowSet.getBaseRootFile();
        File file = FileUtil.file(rootFile, date + File.separator + processId + File.separator + processVersion + File.separator + tid + File.separator + dbFile);
        if (!file.exists()) {
            return Collections.emptyList();
        }
        initDb(getJdbcUrl(file), getJdbcDriver(), getJdbcUserName(), getJdbcPassword());

        return getStepList();
    }

    @Override
    public DataSource getDataSource(String date, String processId, String processVersion, String tid, String dbFile, String source, String target) {
        File rootFile = ProcessFileRowSet.getBaseRootFile();
        File file = FileUtil.file(rootFile, date + File.separator + processId + File.separator + processVersion + File.separator + tid + File.separator + dbFile);
        if (!file.exists()) {
            return null;
        }
//        initDb(getJdbcUrl(file), getJdbcDriver(), getJdbcUserName(), getJdbcPassword());

        return super.getDataSource(getJdbcUrl(file), getJdbcDriver(), getJdbcUserName(), getJdbcPassword());
    }

    public Map<String, Object> searchStepDataList(String date, String processId, String processVersion, String tid,
                                                  String dbFile,
                                                  String source,
                                                  String target) {
        File rootFile = ProcessFileRowSet.getBaseRootFile();
        File file = FileUtil.file(rootFile, date + File.separator + processId + File.separator + processVersion + File.separator + tid + File.separator + dbFile);
        if (!file.exists()) {
            return null;
        }
        initDb(getJdbcUrl(file), getJdbcDriver(), getJdbcUserName(), getJdbcPassword());

        setThreadNameFromToCopy(source, 1, target, 1);

        return getStepDataList();
    }


    @Override
    public List<Map<String, Object>> searchProcessList(List<String> dateList) {

        File rootFile = ProcessFileRowSet.getBaseRootFile();

        List<Map<String, Object>> result = Lists.newArrayList();

        for (String date : dateList) {

            File file = FileUtil.file(rootFile, date);
            if (!file.exists()) {
                continue;
            }
            List<File> files = FileUtil.loopFiles(file, 1, null);

            files = files.stream().filter(v -> !StrUtil.containsAnyIgnoreCase(v.getName(), "Ds_Store")).toList();

            for (File processFile : files) {
                String processId = processFile.getName();
                List<File> processVersionFiles = FileUtil.loopFiles(processFile, 1, null);
                processVersionFiles = processVersionFiles.stream().filter(v -> !StrUtil.containsAnyIgnoreCase(v.getName(), "Ds_Store")).toList();

                for (File processVersionFile : processVersionFiles) {
                    String processVersion = processVersionFile.getName();

                    List<File> tidFiles = FileUtil.loopFiles(processVersionFile, 1, null);
                    tidFiles = tidFiles.stream().filter(v -> !StrUtil.containsAnyIgnoreCase(v.getName(), "Ds_Store")).toList();

                    for (File tidFile : tidFiles) {
                        String tid = tidFile.getName();
                        List<File> rowFiles = FileUtil.loopFiles(tidFile, 1, null);
                        rowFiles = rowFiles.stream().filter(v -> !StrUtil.containsAnyIgnoreCase(v.getName(), "Ds_Store")).toList();

                        for (File stepFile : rowFiles) {
                            String rowDb = stepFile.getName();

                            Map<String, Object> map = Maps.newHashMap();
                            map.put("type", typeCode());
                            map.put("processId", processId);
                            map.put("processVersion", processVersion);
                            map.put("tid", tid);
                            map.put("date", date);
                            map.put("dbFile", rowDb);
                            result.add(map);
                        }
                    }
                }
            }
        }
        return result;
    }

    @Override
    protected String getJdbcUserName() {
        return "root";
    }

    @Override
    protected String getJdbcPassword() {
        return "123456";
    }

    @Override
    protected String getJdbcUrl() {
        File projectFile = createProjectFile();
        return initFiles(projectFile.getPath() + "/row.db");
    }

    protected String getJdbcUrl(File file) {
        return initFiles(file.getPath());
    }

    @Override
    protected String getJdbcDriver() {
        return "org.sqlite.JDBC";
    }

    @SneakyThrows
    private String initFiles(String file) {

        return "jdbc:sqlite:" + file;
    }


    private File createProjectFile() {
        return createProjectFile(createRootFile(), this.processInstance);
    }

    private File createProjectFile(File rootFile, ProcessInstance processTrans) {
        if (ObjectUtil.isNull(rootFile)) {
            rootFile = createRootFile();
        }
        if (ObjectUtil.isNull(processTrans)) {
            processTrans = this.processInstance;
        }

        String processId = processTrans.getProcessId();
        String processVersion = processTrans.getProcessVersion();
        String tid = processTrans.getTid();

        File file = null;
        if (StrUtil.isNotBlank(tid)) {
            file = FileUtil.file(rootFile.getPath(), processId + File.separator + processVersion + File.separator + tid);
        } else {
            file = FileUtil.file(rootFile.getPath(), processId + File.separator + processVersion);
        }
//        this.getor
        //创建文件

        if (!file.exists()) {
            synchronized (ProcessFileRowSet.class) {
                if (!file.exists()) {
                    file.mkdir();
                }
            }
        }
        return file;
    }


    public Boolean writeDbFlag() {
        if (ObjectUtil.isNull(processInstance)) {
            return false;
        }
        String tid = this.processInstance.getTid();

        if (StrUtil.isBlank(tid)) {
            return false;
        }
        return true;
    }

    @Override
    public String typeCode() {
        return ProcessRowSetEnum.FILE.getCode();
    }


    @SneakyThrows
    public static File createRootFile() {

        File baseRootFile = getBaseRootFile();
        String format = DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_PATTERN);

        File file = FileUtil.file(baseRootFile, format);
        if (!file.exists()) {
            synchronized (ProcessFileRowSet.class) {
                if (!file.exists()) {
                    file.mkdir();
                }
            }
        }
        return file;
    }

    public static File getBaseRootFile() {
        String property = System.getProperty("user.home");

        File file = FileUtil.file(property + File.separator + "square_lake" + File.separator + "rowSet");
        if (!file.exists()) {
            synchronized (ProcessFileRowSet.class) {
                if (!file.exists()) {
                    file.mkdir();
                }
            }
        }
        return file;
    }


}
